<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/11/11 0011
 * Time: 下午 5:22
 */

namespace common\Com;


use yii\base\Exception;

class CurlMatch
{
    public $_curl;
    public $_content_con;
    public $_http_host = '';
    public $_debug = false;
    public $_tag = 'div';
    public $_host = "";
    public $_data = "";

    public $_list_con = '/\<a[^\>]*href=[\"\']?(.*?)[\"\'][^\>]*\>(.*?)\<\/a\>/';
    public $_host_con = '/(http[s]?:\/\/)?(.*?\.[^\/]*)(\/)?(.*)/';
    public function __construct()
    {
        $this->_curl = new Curl();
        $this->_curl->init();
    }

    /**
     * @author       :   DuYongGao
     * @name         :   content
     * @description  :  抓取单页面的文本内容内容
     * @param $url
     * @param $key  存储单页面内容的标签
     * @return null
     */
    public function content($url,$key , $charset = 'utf8'){
        $data = $this->get($url);
        return ($charset=='utf8')?$this->match($key ,$data , 'content'):mb_convert_encoding( $this->match($key ,$data , 'content') ,'UTF-8','GBK');
    }

    public function get($url, $charset = 'utf8'){
        $url = $this->urlFix($url);
        if($this->_debug){
            var_dump($url);
        }
        $data = $this->_curl->get($url);
        $this->_data = ($charset=='utf8')? $data : mb_convert_encoding($data  ,'UTF-8','GBK');
        return $this->_curl->get($url);
    }

    /**
     * @author       :   DuYongGao
     * @name         :   setHost
     * @description  :  根据路径，保存抓取站点的域名信息
     * @param $url
     * @return bool
     */
    public function urlFix($url){
        if(preg_match($this->_host_con , $url , $out)){
            empty($this->_http_host) && $this->_http_host = (isset($out[1]) && !empty($out[1])?$out[1]:'http://').(isset($out[2])?$out[2]:'');
            return $this->_http_host.'/'.(isset($out[4]) ? $out[4] :'');
        }
        return '';
    }

    /**
     * @author       :   DuYongGao
     * @name         :   alist
     * @description  :  抓取列表
     * @param $url
     * @param $key
     * @return null
     */
    public function alist($url,$key){
        $this->_host = $this->getHost($url);
        $data = $this->content($url,$key);
        return $this->match($key ,$data , 'list');
    }

    /**
     * @author       :   DuYongGao
     * @name         :   match
     * @description  :  根据类型返回页面抓取结果
     * @param $key
     * @param $data
     * @param $type
     * @return array|null
     */
    public function match($key,$data,$type){
        switch($type){
            case 'content':
                $this->setContentCon($key);
                if(preg_match($this->_content_con,$data,$out)){
                    $realContent = $this->realContent($out[1]);
                    return !empty($realContent)?$realContent:$out[1];
                }
                break;
            case 'data':
                $this->setContentCon($key);
                if(preg_match($this->_content_con,$data,$out)){
                    return isset($out[1])?$out[1]:NULL;
                }
                break;
            case 'list':
                if(preg_match_all($this->_list_con,$data,$out)){
                    return isset($out[1])?$out[1]:[];
                }
                return [];
                break;
        }
        return NULL;
    }

    /**
     * @author       :   DuYongGao
     * @name         :   parseKey
     * @description  :  解析匹配的键
     * @param $key
     * @return null
     */
    public function parseKey($key){
        if(preg_match('/^\<([^\>]*)\>.*\<\/([^\>]+)\>$/',$key,$out)){
            $this->_tag = (isset($out[2]) && !empty($out[2]))?$out[2]:'div';
            return $out;
        }
        return NULL;
    }
    public function realContent($content){
        $tag = $this->_tag;
        $start = '<'.$tag;
        $end = '</'.$tag;
        $index = 0;
        $fist_end_tag = strpos($content,$end);
        $str = substr($content,0 , $fist_end_tag);
        if(!($num = preg_match_all('/'.$this->_curl->curl_quote($start).'/' , $str))){
            return $str;
        }else{
            $index = $index+$num -1;
            $length_end = strlen($end);
            $length_start = strlen($start);
            $str_two = substr($content , $fist_end_tag+$length_end);
            for($i=0,$length=strlen($str_two);$i<$length;$i++){
                (substr($str_two,$i,$length_start) == $start) && $index++;//匹配开始
                (substr($str_two,$i,$length_end) == $end) && $index--;//匹配结束标记
                if($index == -1){
                    break;
                }
            }
            return $str.$start.substr($str_two,0,$i);
        }
    }

    /**
     * @author       :   DuYongGao
     * @name         :   setContentCon
     * @description  :  设置文本查询条件
     * @param $key
     */
    public function setContentCon($key){
        $out = $this->parseKey($key);
        is_array($out) && $this->_content_con = '/'.$this->_curl->curl_quote("<{$out[1]}>"). '([\s\S]*)'. $this->_curl->curl_quote("</{$out[2]}>").'/';
    }

    public function getHost($url){
        if(preg_match('/(https?:\/\/[^\/]+)/',$url  ,$out)){
            return $out[1];
        }
        throw  new  Exception("未匹配到域名。");
    }

    public function fixUrl($url){
        if(preg_match('/(http[s]:\/\/[^\/]*)?(.*)/',$url,$out) && !empty($this->_host)){
            return $this->_host.''.$url;
        }
        throw new Exception("错误的链接 ");
    }

    public function getPic($url){
        return $this->_curl->get($url);
    }
}